<template>
  <div
    v-if="selectedObject.isSelected"
    class="c-editor-move-bar__container"
    :style="{ '--top': selectedObject.top, '--left': selectedObject.left }"
    :class="{
      'c-editor-move-bar__marker-pen': selectedObject.type === 'markerPen',
    }"
  >
    <a-flex justify="center" align="center">
      <template v-if="!editOptions.lock">
        <template v-if="selectedObject.type === 'shape'">
          <div class="c-editor-move-bar__dropdown">
            <a-tooltip title="填充" placement="top" :mouseEnterDelay="1">
              <a-button type="text" @click="(e: any) => operate(e, 'fill')">
                <template #icon>
                  <BgColorsOutlined />
                  <!--                  class="selectedColor" -->
                  <!--                  :style="{-->
                  <!--                    '&#45;&#45;selectedColor': editOptions.selectedFillColor,-->
                  <!--                  }"-->
                </template>
              </a-button>
            </a-tooltip>
            <div
              class="c-editor-move-bar__dropdown-content"
              v-if="editOptions.option === 'fill'"
            >
              <ColorBoard
                :selected-color-id="editOptions.selectedFillColorId"
                :selected-transparent="editOptions.selectedFillTransparent"
                :fill-transparent-slider="
                  editOptions.fillTransparentSliderDisabled
                "
                @selectColor="(payload) => changeColor(payload, 'fill')"
                @selectTransparent="
                  (payload) => changeTransparent(payload, 'fill')
                "
                type="fill"
              />
            </div>
          </div>
        </template>
        <template
          v-if="
            !(
              selectedObject.type == 'textbox' ||
              selectedObject.type == 'activeSelection'
            )
          "
        >
          <div class="c-editor-move-bar__dropdown">
            <a-tooltip title="边框" placement="top" :mouseEnterDelay="1">
              <a-button type="text" @click="(e: any) => operate(e, 'border')">
                <template #icon>
                  <BorderOuterOutlined />
                </template>
              </a-button>
            </a-tooltip>
            <div
              class="c-editor-move-bar__dropdown-content"
              v-if="editOptions.option === 'border'"
            >
              <ColorBoard
                :min-thickness="
                  selectedObject.type === 'arrow' ||
                  selectedObject.type === 'line'
                    ? 2
                    : 1
                "
                :max-thickness="
                  selectedObject.type === 'arrow' ||
                  selectedObject.type === 'line'
                    ? 10
                    : 30
                "
                :border-style="editOptions.selectedBorderStyle"
                :selected-color-id="editOptions.selectedBorderColorId"
                :selected-transparent="editOptions.selectedBorderTransparent"
                :selected-border-thickness="editOptions.selectedBorderThickness"
                :type="
                  selectedObject.type === 'arrow' ||
                  selectedObject.type === 'line'
                    ? 'line'
                    : 'border'
                "
                @selectColor="(payload) => changeColor(payload, 'border')"
                @selectTransparent="
                  (payload) => changeTransparent(payload, 'border')
                "
                @selectThickness="changeBorderThickness"
                @selectBorderStyle="changeBorderStyle"
              />
            </div>
          </div>

          <a-divider type="vertical" class="divider" />
        </template>
        <template v-if="selectedObject.type === 'textbox'">
          <a-flex style="margin-right: 3px">
            <div class="c-editor-move-bar__dropdown">
              <a-tooltip title="字体类型" placement="top" :mouseEnterDelay="1">
                <a-button
                  type="text"
                  @click="(e: any) => operate(e, 'textFamily')"
                >
                  {{ editOptions.selectedTextFamily }}
                </a-button>
              </a-tooltip>
              <div
                class="c-editor-move-bar__dropdown-content"
                v-if="editOptions.option === 'textFamily'"
              >
                <a-flex vertical>
                  <div
                    v-for="item in textFamilyList"
                    :key="item.id"
                    class="c-editor-move-bar__dropdown-content-item"
                    :class="{
                      'dropdown-item-click':
                        editOptions.selectedTextFamily === item.typeName,
                    }"
                    @click="changeTextFamily(item.typeName)"
                  >
                    {{ item.typeName }}
                  </div>
                </a-flex>
              </div>
            </div>
            <a-tooltip title="文字大小" placement="top" :mouseEnterDelay="1">
              <a-input-number
                class="c-editor-move-bar__change-size-box"
                v-model:value="editOptions.selectedTextSize"
                :default-value="10"
                :min="10"
                :max="288"
                @change="changeTextSize"
              ></a-input-number>
            </a-tooltip>
          </a-flex>
          <a-divider type="vertical" class="divider" />
          <div class="c-editor-move-bar__dropdown">
            <a-tooltip title="文字样式" placement="top" :mouseEnterDelay="1">
              <a-button
                type="text"
                :icon="h(BoldOutlined)"
                @click="(e: any) => operate(e, 'textStyle')"
              ></a-button>
            </a-tooltip>
            <div
              class="c-editor-move-bar__dropdown-content"
              v-if="editOptions.option === 'textStyle'"
            >
              <a-flex>
                <BoldOutlined
                  class="c-editor-move-bar__button-icon"
                  :class="{
                    'dropdown-item-click':
                      editOptions.selectedTextStyle.includes('bold'),
                  }"
                  @click="changeTextStyle('bold')"
                />
                <ItalicOutlined
                  class="c-editor-move-bar__button-icon"
                  :class="{
                    'dropdown-item-click':
                      editOptions.selectedTextStyle.includes('italic'),
                  }"
                  @click="changeTextStyle('italic')"
                />
                <UnderlineOutlined
                  class="c-editor-move-bar__button-icon"
                  :class="{
                    'dropdown-item-click':
                      editOptions.selectedTextStyle.includes('underline'),
                  }"
                  @click="changeTextStyle('underline')"
                />
                <StrikethroughOutlined
                  class="c-editor-move-bar__button-icon"
                  :class="{
                    'dropdown-item-click':
                      editOptions.selectedTextStyle.includes('linethrough'),
                  }"
                  @click="changeTextStyle('linethrough')"
                />
              </a-flex>
            </div>
          </div>
          <div class="c-editor-move-bar__dropdown">
            <a-tooltip title="文字对齐" placement="top" :mouseEnterDelay="1">
              <a-button
                type="text"
                :icon="h(AlignCenterOutlined)"
                @click="(e: any) => operate(e, 'textAlign')"
              ></a-button>
            </a-tooltip>
            <div
              class="c-editor-move-bar__dropdown-content"
              v-if="editOptions.option === 'textAlign'"
            >
              <a-flex>
                <AlignLeftOutlined
                  class="c-editor-move-bar__button-icon"
                  :class="{
                    'dropdown-item-click':
                      editOptions.selectedTextAlign === 'left',
                  }"
                  @click="changeTextAlign('left')"
                />
                <AlignCenterOutlined
                  class="c-editor-move-bar__button-icon"
                  :class="{
                    'dropdown-item-click':
                      editOptions.selectedTextAlign === 'center',
                  }"
                  @click="changeTextAlign('center')"
                />
                <AlignRightOutlined
                  class="c-editor-move-bar__button-icon"
                  :class="{
                    'dropdown-item-click':
                      editOptions.selectedTextAlign === 'right',
                  }"
                  @click="changeTextAlign('right')"
                />
              </a-flex>
            </div>
          </div>
          <div class="c-editor-move-bar__dropdown">
            <a-tooltip title="文字颜色" placement="top" :mouseEnterDelay="1">
              <a-button
                type="text"
                @click="(e: any) => operate(e, 'textColor')"
              >
                <template #icon>
                  <FontColorsOutlined />
                  <!--                  class="selectedColor"-->
                  <!--                  :style="{-->
                  <!--                  '&#45;&#45;selectedColor': editOptions.selectedTextColor,-->
                  <!--                  }"-->
                </template>
              </a-button>
            </a-tooltip>
            <div
              class="c-editor-move-bar__dropdown-content"
              v-if="editOptions.option === 'textColor'"
            >
              <ColorBoard
                @selectColor="(payload) => changeColor(payload, 'text')"
                :selected-color-id="editOptions.selectedTextColorId"
                type="color"
              />
            </div>
          </div>
          <div class="c-editor-move-bar__dropdown">
            <a-tooltip title="行高" placement="top" :mouseEnterDelay="1">
              <a-button
                type="text"
                :icon="h(LineHeightOutlined)"
                @click="(e: any) => operate(e, 'lineHeight')"
              ></a-button>
            </a-tooltip>
            <div
              class="c-editor-move-bar__dropdown-content"
              v-if="editOptions.option === 'lineHeight'"
            >
              <a-flex vertical>
                <div
                  v-for="item in lineHeightList"
                  class="c-editor-move-bar__dropdown-content-item"
                  :class="{
                    'dropdown-item-click':
                      editOptions.selectedLineHeight === item,
                  }"
                  @click="changeLineHeight(item)"
                >
                  {{ item }}
                </div>
              </a-flex>
            </div>
          </div>
          <a-divider type="vertical" class="divider" />
        </template>
      </template>
      <a-tooltip
        title="锁定"
        placement="top"
        :mouseEnterDelay="1"
        v-if="!editOptions.lock"
      >
        <a-button
          type="text"
          :icon="h(UnlockOutlined)"
          @click="lockElement('lock')"
        ></a-button>
      </a-tooltip>
      <a-tooltip title="解锁" placement="top" :mouseEnterDelay="1" v-else>
        <a-button
          type="text"
          :icon="h(LockOutlined)"
          @click="lockElement('unlock')"
        >
          解锁
        </a-button>
      </a-tooltip>
    </a-flex>
  </div>
</template>

<script setup lang="ts">
import { inject, onMounted, reactive, h } from 'vue';
import { IEditor } from '@/types/global';
import ColorBoard from '@/components/ColorBoard.vue';
import {
  BorderOuterOutlined,
  UnlockOutlined,
  AlignCenterOutlined,
  BoldOutlined,
  FontColorsOutlined,
  LineHeightOutlined,
  ItalicOutlined,
  UnderlineOutlined,
  StrikethroughOutlined,
  AlignLeftOutlined,
  AlignRightOutlined,
  BgColorsOutlined,
  LockOutlined,
} from '@ant-design/icons-vue';
import { textFamilyList, lineHeightList } from '@/utils/Const.ts';
import { getColorListFromRGBA, setColorAndAlpha } from '@/utils/Filter.ts';

// 白板编辑器对象，操作画布
const canvasEditor: unknown | IEditor = inject('canvasEditor');
const editOptions = reactive({
  option: '',
  selectedFillColor: 'transparent',
  selectedFillColorId: '0',
  selectedFillTransparent: 100,
  fillTransparentSliderDisabled: true,

  selectedBorderThickness: 3,
  selectedBorderColor: 'rgba(0, 0, 0, 1)',
  selectedBorderColorId: '',
  selectedBorderTransparent: 100,
  selectedBorderStyle: 'line',

  selectedTextSize: 18,
  selectedTextFamily: '思源黑体',
  selectedTextStyle: [],
  selectedTextAlign: 'left',
  selectedTextColor: 'rgba(0, 0, 0, 1)',
  selectedTextColorId: '',
  selectedLineHeight: 1,
  lock: false,
});

// 移动菜单栏 显示功能 start
const selectedObject = reactive({
  target: null,
  isSelected: false,
  top: '0',
  left: '0',
  type: '',
  fontSize: 0,
  stroke: 'rgba(0, 0, 0, 1)',
  strokeWidth: 5,
});
function initEditOptions(type: string, target: any) {
  if (type === 'shape') {
    if (target.fill === 'transparent') {
      editOptions.selectedFillTransparent = 100;
      editOptions.selectedFillColorId = '0';
      editOptions.fillTransparentSliderDisabled = true;
    } else {
      const fillTransparent = getColorListFromRGBA(target.fill);
      editOptions.selectedFillTransparent = Number(fillTransparent[3]) * 100;
      editOptions.selectedFillColorId = '';
      editOptions.fillTransparentSliderDisabled = false;
    }
    const borderTransparent = getColorListFromRGBA(target.stroke);
    editOptions.selectedBorderColorId = '';
    editOptions.selectedBorderTransparent = Number(borderTransparent[3]) * 100;
    editOptions.selectedBorderThickness = target.strokeWidth;
    if (!target.strokeDashArray || target.strokeDashArray.length === 0) {
      editOptions.selectedBorderStyle = 'line';
    } else {
      editOptions.selectedBorderStyle =
        target.strokeDashArray[0] < 5 ? 'smallDash' : 'dash';
    }
  } else if (type === 'arrow' || type === 'line') {
    if (!target.strokeDashArray || target.strokeDashArray.length === 0) {
      editOptions.selectedBorderStyle = 'line';
    } else {
      editOptions.selectedBorderStyle =
        target.strokeDashArray[0] < 15 ? 'smallDash' : 'dash';
    }
  } else if (type === 'path') {
    const borderTransparent = getColorListFromRGBA(target.stroke);
    editOptions.selectedBorderTransparent = Number(borderTransparent[3]) * 100;
    editOptions.selectedBorderThickness = target.strokeWidth;
    editOptions.selectedBorderColor = target.stroke;
    if (!target.strokeDashArray || target.strokeDashArray.length === 0) {
      editOptions.selectedBorderStyle = 'line';
    } else {
      editOptions.selectedBorderStyle =
        target.strokeDashArray[0] < 25 ? 'smallDash' : 'dash';
    }
  } else if (type === 'textbox') {
    editOptions.selectedTextColorId = '';
    editOptions.selectedTextFamily = target.fontFamily;
    editOptions.selectedTextSize = target.fontSize;
    editOptions.selectedLineHeight = target.lineHeight;
    editOptions.selectedTextAlign = target.textAlign;
    if (target.fontStyle === 'italic') {
      editOptions.selectedTextStyle.push('italic');
    } else {
      editOptions.selectedTextStyle = editOptions.selectedTextStyle.filter(
        (item) => item !== 'italic',
      );
    }
    if (target.fontWeight === 'bold') {
      editOptions.selectedTextStyle.push('bold');
    } else {
      editOptions.selectedTextStyle = editOptions.selectedTextStyle.filter(
        (item) => item !== 'bold',
      );
    }
    if (target.linethrough) {
      editOptions.selectedTextStyle.push('linethrough');
    } else {
      editOptions.selectedTextStyle = editOptions.selectedTextStyle.filter(
        (item) => item !== 'linethrough',
      );
    }
    if (target.underline) {
      editOptions.selectedTextStyle.push('underline');
    } else {
      editOptions.selectedTextStyle = editOptions.selectedTextStyle.filter(
        (item) => item !== 'underline',
      );
    }
  }
}
onMounted(() => {
  canvasEditor.on('selecting', (data: any) => {
    selectedObject.isSelected = data.isSelected;
    if (selectedObject.isSelected) {
      const object = canvasEditor.getActiveObject();
      selectedObject.top = `${object.top}px`;
      selectedObject.left = `${object.left}px`;
      selectedObject.target = object.activeObject;
      const { type } = object;
      if (
        type === 'rect' ||
        type === 'triangle' ||
        type === 'circle' ||
        type === 'ellipse'
      ) {
        selectedObject.type = 'shape';
      } else if (type === 'activeSelection') {
        canvasEditor.lockSelection();
        selectedObject.type = object.type;
      } else {
        selectedObject.type = object.type;
      }
      editOptions.lock = selectedObject.target.lock;
      if (editOptions.lock) {
        selectedObject.target.hasControls = false;
      }
      initEditOptions(selectedObject.type, selectedObject.target);
    } else {
      editOptions.option = '';
    }
  });
});
// 移动菜单栏 显示功能 end

// 选择
function operate(e: any, type: string) {
  if (editOptions.option === type) {
    editOptions.option = '';
    return;
  }
  editOptions.option = type;
}

// 编辑元素功能 start
// 修改字体类型
function changeTextFamily(type: string) {
  editOptions.selectedTextFamily = type;
  canvasEditor.setTextFontFamily(type);
  editOptions.option = '';
}

// 修改文字大小
function changeTextSize(value: number) {
  canvasEditor.setTextSize(value ? value : 25);
  editOptions.option = '';
}

// 修改文字样式
function changeTextStyle(styleName: string) {
  const { selectedTextStyle } = editOptions;
  if (selectedTextStyle.includes(styleName)) {
    changeTextObject(styleName, false);
    const styleList = selectedTextStyle.filter((item) => {
      return item !== styleName;
    });
    editOptions.selectedTextStyle = [...styleList];
  } else {
    selectedTextStyle.push(styleName);
    changeTextObject(styleName, true);
  }
  editOptions.option = '';
}

function changeTextObject(style: string, bool: boolean) {
  switch (style) {
    case 'bold':
      canvasEditor.setTextBold(bool);
      break;
    case 'italic':
      canvasEditor.setTextItalic(bool);
      break;
    case 'underline':
      canvasEditor.setTextUnderLine(bool);
      break;
    case 'linethrough':
      canvasEditor.setTextLinethrough(bool);
      break;
  }
}

// 修改文字对齐
function changeTextAlign(type: string) {
  editOptions.selectedTextAlign = type;
  canvasEditor.setTextAlign(type);
  editOptions.option = '';
}

// 修改文字、图形边框、图形填充的颜色
function changeColor(payload: any, type: string) {
  let color = payload.color;
  switch (type) {
    case 'text':
      editOptions.selectedTextColor = payload.color;
      editOptions.selectedTextColorId = payload.colorId;
      canvasEditor.setTextColor(color);
      break;
    case 'fill':
      editOptions.selectedFillColor = payload.color;
      editOptions.selectedFillColorId = payload.colorId;
      if (payload.color === 'transparent') {
        editOptions.fillTransparentSliderDisabled = true;
      } else {
        color = setColorAndAlpha(
          payload.color,
          editOptions.selectedFillTransparent,
        );
        editOptions.fillTransparentSliderDisabled = false;
      }
      canvasEditor.setShapeFillColor(color);
      break;
    case 'border':
      editOptions.selectedBorderColor = payload.color;
      editOptions.selectedBorderColorId = payload.colorId;
      color = setColorAndAlpha(
        payload.color,
        editOptions.selectedBorderTransparent,
      );
      if (selectedObject.type === 'path') {
        canvasEditor.setBrushColor(color);
      } else if (selectedObject.type === 'shape') {
        canvasEditor.setShapeBorderColor(color);
      } else {
        canvasEditor.setLineColor(payload.color);
      }
      break;
  }
  editOptions.option = '';
}

// 修改图形边框、填充的透明度
function changeTransparent(payload: any, type: string) {
  let color = '';
  switch (type) {
    case 'fill':
      if (editOptions.selectedFillColor === 'transparent') {
        color = 'transparent';
        editOptions.fillTransparentSliderDisabled = true;
      } else {
        editOptions.selectedFillTransparent = payload.transparent;
        color = setColorAndAlpha(
          editOptions.selectedFillColor,
          payload.transparent,
        );
        editOptions.fillTransparentSliderDisabled = false;
      }
      canvasEditor.setShapeFillColor(color);
      break;
    case 'border':
      editOptions.selectedBorderTransparent = payload.transparent;
      color = setColorAndAlpha(
        editOptions.selectedBorderColor,
        payload.transparent,
      );
      if (selectedObject.type === 'path') {
        canvasEditor.setBrushColor(color);
      } else {
        canvasEditor.setShapeBorderColor(color);
      }
      break;
  }
  editOptions.option = '';
}

// 修改行高
function changeLineHeight(data: number) {
  editOptions.selectedLineHeight = data;
  canvasEditor.setTextLineHeight(data);
  editOptions.option = '';
}

// 修改图形边框粗细
function changeBorderThickness(payload: any) {
  editOptions.selectedBorderThickness = payload.thickness;
  if (selectedObject.type === 'shape') {
    canvasEditor.setShapeBorderThickness(payload.thickness);
  } else if (selectedObject.type === 'path') {
    canvasEditor.setBrushWidth(payload.thickness);
  } else {
    canvasEditor.setLineWidth(payload.thickness);
  }
  editOptions.option = '';
}

// 修改图形边框样式
function changeBorderStyle(payload: any) {
  editOptions.selectedBorderStyle = payload.style;
  if (selectedObject.type === 'shape') {
    canvasEditor.setShapeBorderStyle(payload.style);
  } else if (selectedObject.type === 'path') {
    canvasEditor.setBrushStyle(payload.style);
  } else {
    canvasEditor.setLineStyle(payload.style);
  }

  editOptions.option = '';
}

// 锁定 / 解锁某元素
function lockElement(option: string) {
  editOptions.option = '';
  editOptions.lock = !editOptions.lock;
  if (option === 'lock') {
    canvasEditor.lockElement();
    console.log('已锁定');
  } else {
    canvasEditor.unLockElement();
    console.log('已解锁');
  }
}

// 编辑元素功能 end
</script>

<style scoped lang="scss">
.c-editor-move-bar__container {
  position: fixed;
  top: var(--top);
  left: var(--left);
  transform: translateX(-50%) translateY(-70%);
  background-color: #fff;
  z-index: 1000;
  box-shadow: 0 3px 5px 1px rgba(0, 0, 0, 0.1);
  padding: 5px;
  .c-editor-move-bar__button-icon {
    cursor: pointer;
    font-size: 18px;
    color: rgba(76, 75, 79, 1);
    border-radius: 2px;
    padding: 5px;
    margin: 2px;
    &:hover {
      background: rgba(185, 185, 185, 0.2);
    }
  }
  .c-editor-move-bar__change-size-box {
    width: 66px;
    margin-left: 10px;
  }
  .divider {
    width: 2px;
    height: 22px;
    border-color: rgba(240, 240, 240, 1);
  }
  .c-editor-move-bar__dropdown {
    position: relative;
    display: inline-block;
    .c-editor-move-bar__dropdown-content {
      position: absolute;
      bottom: 50px;
      left: 50%;
      padding: 3px;
      border-radius: 5px;
      transform: translateX(-50%);
      background-color: #fff;
      box-shadow: 0 -3px 12px 0 rgba(0, 0, 0, 0.2);
      z-index: 999;
      .c-editor-move-bar__dropdown-content-item {
        width: 6rem;
        height: 2rem;
        font-size: 14px;
        text-align: center;
        line-height: 2rem;
        &:hover {
          background: rgba(185, 185, 185, 0.2);
          cursor: pointer;
        }
      }
      .dropdown-item-click {
        font-weight: bold;
        background: rgba(16, 142, 233, 0.1);
      }
    }
  }
}
.c-editor-move-bar__marker-pen {
  transform: translateX(-40%) translateY(-70%);
}
</style>
